使用 JavaScript 升级互联网计算机上的智能合约
在 Papyrs(一个 web3 开源博客平台)上,每个用户在登录时都会获得两个智能合约容器,一个包含私人数据,另一个是用户在互联网上的个人博客空间。
直到我(希望)将所有容器的控制权交给 SNS 和社区的那一天,我可能不得不自己在用户的智能合约中安装新版本的代码 —— 例如,解决问题或部署新功能。
本文介绍了我如何使用 NodeJS 脚本安装代码,以及你如何像我一样安装代码。
入门
今年早些时候,我发表了两篇相关文章:
在 NodeJS 中调用互联网计算机容器
这些文章导致了本教程,第一个解释了如何在 NodeJS 中查询容器,第二个解释了如何动态创建智能合约 —— 即,如何创建容器,我可以在其中安装更新版本的代码。
子容器
我使用上面两个帖子中的第一个来创建一个本地示例项目,在编译和部署到本地模拟 IC 网络之后,我打开浏览器并动态创建一个子容器 renrk-eyaaa-aaaaa-aaada-cai。
这个示例智能合约是我打算在接下来的章节中更新的,这就是为什么我通过如下修改它的源代码来提升它的版本:
修改后,我必须重新生成将要安装的 WebAssembly(Wasm)二进制文件 —— 部署到 IC,为此,我必须遵循我在上一篇文章中分享的解决方法,因为目前“没有其他方法可以将导入类的 Wasm 作为单独的非嵌入式事物生成”。
编辑配置 dfx.json 以列出存储桶参与者。
运行 dfx deploy 命令生成文件,该命令将以错误结束,“错误 - 无效数据:预期的参数,但没有找到”,可以安全地忽略。
在 dfx.json 中还原更改。
后端
只有容器的控制器可以安装新版本的代码,由于子容器是由主要 actor 创建的 —— 我将其命名为 manager —— 我必须注意将其主体添加到控制器列表中,同时更新我之前教程中的设置。
所以在这个解决方案中,这个参与者将安装代码,NodeJS 脚本将仅作为调用者。
安装代码的后端功能 —— install_code —— 是 IC 接口规范的一部分,因此,我可以在我的 manager 中添加一个功能,作为代理接收信息并调用 IC的核心功能。
重要提示:以下代码片段是公共函数,如果您在 mainnet 智能合约中实施此类功能,请采取适当的安全预防措施。
要在我的目标容器中安装代码,我需要四个参数:
目标容器 ID。
Wasm 模块 —— 我在前一章中构建的 Wasm 代码的新版本以及我的解决方法。
一个 mode 用于 #upgrade 执行容器升级中描述的更新 —— 目标是保持状态。
参数 —— 用于初始化容器的参数。
NodeJS 脚本
我可以在我命名为 installcode.mjs 的 NodeJS 模块脚本中实现对 manager 端点的调用,该脚本将在有效调用我的 actor(函数 upgradeBucket)之前收集上述参数。
第一个参数是作为 Principal 的目标容器 ID,当我在浏览器控制台中打印本地子容器的 id — renrk-eyaaa-aaaaa-aaada-cai — 时,我将本地子容器收集为 string,我需要在 Principal.fromText() 的帮助下对其进行转换。
我需要的第二个参数是 Wasm 模块,为了收集它,我可以读取之前运行 dfx deploy 时生成的文件,并将其转换为 ArrayBuffer —— 与后端参与者代码中定义的 Blob 匹配的预期类型。
第三个参数是与那些用于动态创建容器的参数相匹配的参数,具体来说,本教程的 bucket 的 actors 是用一个 user 参数:
因此,要安装代码,我需要提供必须用 Candid 编码的相同参数(否则参数将被拒绝):
请注意,IDL 支持各种格式 —— 例如,如果 Motoko 参数是一个 Principal,我可以将其编码如下:
要实例化 manager actor,一旦我找到它的容器 ID,我可以像通常使用 agent-js 一样继续:
但是,有一个微妙之处:因为我正在编写一个模块脚本 - .mjs - 我无法将 dfx 自动生成的 idlFactory 脚本作为 .js 文件 import。
为了克服这个问题,我只需要复制它来更改它的扩展名,幸运的是,这可以解决问题。
部署在本地模拟 IC 上的 manager 的主体 ID 可以在 .dfx 文件夹中找到。
最终,如果您要在 mainnet 上部署,您将能够在项目根目录下的 canister_ids.json 中找到相同的信息。
请注意,您还必须注释 fetchRootKey 并在 HttpAgent 初始化中更改 host 属性。
终于可以用我收集的参数来实现安装代码的有效调用了。
测试
一切都准备好了,我可以调用我的 NodeJS 脚本 —— node installcode.mjs。
安装成功,为了确定代码已部署,然后我调用了容器(已更新)以检查它现在确实返回了新版本 v2 —— 我期待,现在它确实成功了。
结论和样本 repo
您可以在我在 GitHub 上发布的示例 repo 中找到本教程的源代码:
github.com/peterpeterparker/manager
我希望它对社区有用,如果您有改进的想法,请告诉我,如需更多冒险,请在 Twitter(@daviddalbusco)上关注我。
到无限和超越,David。
在 internetcomputer.org 上开始构建,并在 forum.dfinity.org 加入开发者社区。
作者:David Dal Busco
翻译:Catherine
- 往 期 推 荐 -
Azle:适用于互联网计算机上 JavaScript 开发人员的 TypeScript CDK
无处可通的链桥 - 为什么链桥会被黑客入侵以及 IC 将如何解决桥接困境?
长按关注 DFINITY 微信公众号
随时答疑解惑
*添加小助手微信 comiocn 进交流社群